home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
escalant
/
escala21.lha
/
escalante2.1
/
src
/
gm
/
PVGraphElement.h
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-15
|
14KB
|
568 lines
//
// Copyright (C) 1993 Jeff McWhirter
//
#ifndef PVGraphElement_h
#define PVGraphElement_h
#include "EscalanteGlobal.h"
#include "GraphObject.h"
#include "CommonElt.h"
#include "ObjList.h"
class Class;
//class defs
class PVRelation;
class PVGraphElement;
void WriteOutVSet(OStream & o);
void ReadInVSet(IStream & o);
extern bool gVSetIO;
extern ObjList * gVProtoList;
void SetCurrentVGraphElementSet(Set *s);
Set * GetVGraphElementSet();
void KillVGraphElements();
Set * GetVDieSet();
void SetCurrentVDieSet(Set * s);
void InVDie(bool f);
void StartVDie();
void EndVDie();
#define VITERDEP(element,ename,rname,dir,dep,deptype) {\
Iter eltloopiter((element)->GetRelations(dir));\
while(rname=(VRelation*)eltloopiter()) \
if(rname->GetEventDep(dep,deptype)){\
ename = (VGraphElement*)rname->GetOtherElement((element));
#define ENDVITERDEP }}
enum PVGraphElementFlags{
ePVGEPropagating = BIT(eGOLast+1),
ePVGECopied = BIT(eGOLast+2),
ePVAdding = BIT(eGOLast+3),
ePVOkToWriteOut = BIT(eGOLast+4),
ePVOkToWriteOut2 = BIT(eGOLast+5),
ePVGraphElementLast = eGOLast+5
};
//Propagation stuff
typedef bool (*VPropFunc)(PVGraphElement*root,
PVRelation* rel, PVGraphElement* target,
void * data,
int hops ,
bool & b
);
typedef bool (*VPathFunc)(PVGraphElement*root,
PVRelation* rel, PVGraphElement* target,
void * data, int hops
);
typedef bool (*PVRelationOKFunc)(PVRelation*,void* );
#define PVGraphElement_BASE GraphObject
//
//The following objects are group objects and are used to group a set
//of incident relations or the connected elements of incident relations.
//The OkToAdd Objects are used to determine if it is ok to add and element
//to a group. The OkToAdd class determines whether we are grouoing input or
//output relations. The RelXElt class decides based on the type of
//relation and element.
//
//The group objects take use an OkToAdd object to determine when an element
//should be added to a group.
//The Group::relProto and Group::firstProto attributes are ptrs to relations.
//The firstProto is used to add a relation between the element and the first element
//in the group. The relProto is used to add relations between each successive element
//in the group
//
//The RelGroup groups incident relations the EltGroup groups the other elements
//of incident relations
//
#ifdef USEGROUP
class VOkToAdd: public Object{
public:
RDir dir;
MetaDef(VOkToAdd);
VOkToAdd(RDir d = eInOut){dir = d;}
virtual bool InRelationOk(PVRelation *){
return (dir== eIn || dir == eInOut);
}
virtual bool OutRelationOk(PVRelation *){
return (dir== eOut || dir == eInOut);
}
virtual bool HeadOk(PVGraphElement *,PVRelation *){
return (dir== eOut || dir == eInOut);
}
virtual bool TailOk(PVGraphElement *,PVRelation *){
return (dir== eIn || dir == eInOut);
}
OStream& PrintOn(OStream&);
IStream& ReadFrom(IStream&);
};
class VRelXElt: public VOkToAdd{
public:
class Class* relc;
class Class* eltc;
MetaDef(VRelXElt);
VRelXElt(Class * r,Class * e=0,RDir dir = eInOut):VOkToAdd(dir){
relc =r; eltc=e;
}
bool InRelationOk(PVRelation * );
bool OutRelationOk(PVRelation *);
bool HeadOk(PVGraphElement * ,PVRelation * );
bool TailOk(PVGraphElement * ,PVRelation * );
OStream& PrintOn(OStream&);
IStream& ReadFrom(IStream&);
};
enum VGroupFlags{
eVKillRel = BIT(eGOLast+1),
eVGroupLast = eGOLast+1};
class VGroup: public Object{
public:
int id;
VOkToAdd * criteria;
PVGraphElement * theelt;
PVRelation * relProto;
PVRelation * firstProto;
ObjList* elts;
MetaDef(VGroup);
void InitClone(){elts=0;}
VGroup(PVGraphElement * telt,PVRelation * proto,VOkToAdd * crit=0,PVRelation * fp=0){
theelt= telt;relProto = proto;criteria = crit;elts=0; firstProto=fp;
}
~VGroup();
void DoObserve(int id, int part, void *d , Object *op);
int GetId(){return id;}
void SetId(int i){id =i;}
virtual void AddElement(PVGraphElement*);
virtual void RemoveElement(PVGraphElement * );
void SetElement(PVGraphElement * elt){theelt = elt;}
virtual void AddedInRelation(PVRelation * ){}
virtual void RemovedInRelation(PVRelation * ){}
virtual void AddedOutRelation(PVRelation * ){}
virtual void RemovedOutRelation(PVRelation *){}
virtual void NewTail(PVRelation * ,PVGraphElement* ,PVGraphElement*){}
virtual void NewHead(PVRelation * ,PVGraphElement*,PVGraphElement* ){}
void Connect(PVGraphElement * e1,PVGraphElement * e2);
OStream& PrintOn(OStream&);
IStream& ReadFrom(IStream&);
};
class VRelGroup: public VGroup{
public:
MetaDef(VRelGroup);
VRelGroup(class PVGraphElement * telt,PVRelation * proto,class VOkToAdd * cl,PVRelation* firstProto =0):
VGroup(telt,proto,cl,firstProto){}
void RemovedInRelation(PVRelation * r){RemoveElement((PVGraphElement*)r );}
void RemovedOutRelation(PVRelation * r){RemoveElement((PVGraphElement*)r);}
void AddedRelation(PVRelation * r,RDir dir);
void AddedInRelation(PVRelation * r){AddedRelation(r,eIn);}
void AddedOutRelation(PVRelation * r){AddedRelation(r,eOut);}
};
class VEltGroup: public VGroup{
public:
MetaDef(VEltGroup);
VEltGroup(class PVGraphElement * telt,PVRelation * proto,class VOkToAdd * cl,PVRelation* firstProto=0):
VGroup(telt,proto,cl,firstProto){}
void RemovedInRelation(PVRelation * r);
void RemovedOutRelation(PVRelation * r);
void AddedInRelation(PVRelation * r);
void AddedOutRelation(PVRelation * r);
void NewElt(RDir dir,PVRelation *r ,PVGraphElement* newtl,PVGraphElement* oldtl =0);
void NewTail(PVRelation *r ,PVGraphElement* newtl,PVGraphElement* oldtl =0){
NewElt(eIn,r,newtl,oldtl);
}
void NewHead(PVRelation *r ,PVGraphElement* newhd,PVGraphElement* oldhd =0 ){
NewElt(eOut,r,newhd,oldhd);
}
};
#endif USEGROUP
class PVGraphElement: public GraphObject{
public:
//
//A list of prototypes for this element. Used in the EscalanteView palette and
//for adding elements and finding default relations
//
ObjList * protos;
//
//The incoming and outgoing relations. An InRel is one in which this
//element is the hd of the relations. OutRel -> this element is the tail
//
ObjList * InRels;
ObjList * OutRels;
//
//Used in event propagation
//
long int eventMask;
long int affectedByEvents;
char * name;
MetaDef(PVGraphElement);
virtual PVRelation * GetDefaultMemberOf(){return 0;}
PVGraphElement();
~PVGraphElement();
void InitClone();
#ifdef USEGROUP
//
//Group stuff
//
ObjList * groups;
void AddGroup(VGroup * g){
if(groups == 0) groups = new ObjList();
groups->Add(g);
g->SetElement(this);
}
VGroup * GetGroupWithId(int i);
#endif USEGROUP
virtual void AddGroupRelation(PVRelation * r);
virtual char * GetDescription(){return 0;}
bool GetAdding(){return TestFlag(ePVAdding);}
virtual void SetAdding(bool b){SetFlag(ePVAdding,b);}
void SetName(char * nl){
strreplace(&name,nl);
SAC(PVGraphElement,name);
}
char * GetName(){return name;}
void * DoEvent2(Events event, PVGraphElement * elt, void * data, ObjList * list );
virtual void *DoEvent(Events event, PVGraphElement * elt =0, void * data=0);
bool DoneEvent(Events event) {return TestMask(eventMask,event);}
void SetEvent(Events event) {SetMask(eventMask,event);}
void ClearEvent(Events event = eEventNull) {
if(event == eEventNull) eventMask= 0;
else ResetMask(eventMask,event);
}
void * PropagateEvent(Events event,Events notevents, PVGraphElement * elt =0, void * data =0,ObjList * list = 0);
virtual void * PropagateEvent2(Events event,Events notevents, PVGraphElement * elt =0, void * data =0,ObjList * list = 0);
void * PropagateEvent(Events event, PVGraphElement * elt, void * data =0,ObjList * list = 0){
return PropagateEvent( event,(Events)0,elt, data , list );
}
void* GetAttribute(int aid,DataType & type);
void ChangeAttribute(int aid, void * data, DataType type);
void SendAttributeChange(int aid, void * data=0,DataType type = eNullAttrType);
void NewProtos(){protos = new ObjList();}
void AddPrototype(PVGraphElement *e){if(!protos) NewProtos();protos->Add((Object*)e);}
PVGraphElement* GetPrototype(PVGraphElement *e){return (protos?
((protos->Contains((Object*)e))? e:0):
0);}
PVGraphElement* GetPrototypeOfClass(class Class * c);
ObjList * GetPrototypes(){return protos;}
virtual bool AddOnlyIfHaveProto(){return FALSE;}
virtual bool AddOnlyIfHaveDflt(){return FALSE;}
virtual bool AddOnCloning(){return TRUE;}
bool OkToWriteOut(){
return (IfFalseDontWriteOutOriginal() &&
IfFalseDontWriteOutClone() &&
!IsDead());
}
bool IfFalseDontWriteOutOriginal(){return TestFlag(ePVOkToWriteOut);}
void IfFalseDontWriteOutOriginal(bool f){SetFlag(ePVOkToWriteOut,f);}
bool IfFalseDontWriteOutClone(){return TestFlag(ePVOkToWriteOut2);}
void IfFalseDontWriteOutClone(bool f){SetFlag(ePVOkToWriteOut2,f);}
void Die();
void SetDead(bool f);
virtual void MS_Die(){}
bool Copied(){return TestFlag(ePVGECopied);}
void Copied(bool f){SetFlag(ePVGECopied,f);}
PVGraphElement * Copy();
//
//Function propagation stuff
//
//
//You can give an element a function to propagate along its incident
//relations. The first PFunc lets you specify a function (func)
//and data to pass to the function (funcdata)
//the type of relations and elements to propagate along (relc,eltc),
//how many hops (maxhops) to go, and the direction of propagation.
//The function takes the following parameters:
//typedef bool (*VPropFunc)(PVGraphElement*root,
// PVRelation* rel, PVGraphElement* target,
// void * data,
// int hops ,
// bool & b
// );
//Where root is the original element called. rel and target are
//the relation and the target element of the relation,
//hops is the hops so far
//b if FALSE then we exit the entire propagation
//If the function returns FALSE then we don't continue
//propagation with the target
//The second PFunc method lets you specify a function (path) and
//data to pass to that functin (pathdata). This function decides
//which is an ok path to go on.
//
bool Propagating(){return TestFlag(ePVGEPropagating);}
void Propagating(bool f){SetFlag(ePVGEPropagating,f);}
bool PFunc(VPropFunc func,
void * funcdata,
class Class* relc,
class Class* eltc,
int maxhops = MAXINT,
RDir dir= eInOut);
bool PFunc( VPropFunc func ,
void * funcdata,
int maxhops = MAXINT,
RDir dir= eInOut,
VPathFunc path =0 ,
void * pathdata = 0,
ObjList * l =0,
int hopssofar = 0);
OStream& PrintOn(OStream&);
IStream& ReadFrom(IStream&);
//
//These can get called when looking for and element to set the tl or head
//of a relation (in EscalanteView)
//
virtual bool OkToAddInRelation(PVRelation * r){return TRUE;}
virtual bool OkToAddOutRelation(PVRelation * r){return TRUE;}
//
//These methods move in/out relation ptrs to the front/back of the list
//
void MoveRelation(PVRelation * r, RDir dir,bool tofront= TRUE);
void InRelationToFront(PVRelation * r){MoveRelation(r,eIn,TRUE);}
void InRelationToBack(PVRelation * r){MoveRelation(r,eIn,FALSE);}
void OutRelationToFront(PVRelation * r){MoveRelation(r,eOut,TRUE);}
void OutRelationToBack(PVRelation * r){MoveRelation(r,eOut,FALSE);}
//
//These methods return the predecessor/successor (e.g. tl of in rel, hd of out rel)
//for relations of type relClass and pred/succ of type eltClass
//rIsKindOf and eIsKindOf are flags that signal how to check - using IsKindOf or IsA
//
PVGraphElement * Pred(class Class *relClass=0,
class Class * eltClass=0,
bool rIsKindOf = TRUE,
bool eIsKindOf = TRUE);
PVGraphElement * Succ(class Class *relClass=0,
class Class * eltClass=0,
bool rIsKindOf = TRUE,
bool eIsKindOf = TRUE);
//
//These methods are just like the ones above except return the relation
//
PVRelation * RelPred(class Class *relClass=0,
class Class * eltClass=0,
bool rIsKindOf = TRUE,
bool eIsKindOf = TRUE);
PVRelation * RelSucc(class Class *relClass=0,
class Class * eltClass=0,
bool rIsKindOf = TRUE,
bool eIsKindOf = TRUE);
void Pred(Class *relClass,
Class * eltClass,
PVRelation*&,
PVGraphElement*&,
bool rIsKindOf,
bool eIsKindOf);
void Succ(Class *relClass,
Class * eltClass,
PVRelation*&,
PVGraphElement*&,
bool rIsKindOf,
bool eIsKindOf);
//
//Incident relation stuff
//
//
//Getting new relations and tails/heads
//
virtual void AddInRelation(PVRelation *r);
virtual void RemoveInRelation(PVRelation *r);
virtual void AddOutRelation(PVRelation *r);
virtual void RemoveOutRelation(PVRelation *r);
virtual void NewTail(PVRelation * r, PVGraphElement * newtl=0,PVGraphElement* oldtl =0);
virtual void NewHead(PVRelation * r, PVGraphElement * newhd=0,PVGraphElement* oldhd =0);
//
//Return the correct list of relations
//
ObjList * GetRelations(RDir dir = eIn){return (dir == eIn ? InRels : OutRels);}
//
//This find a relation of type c with other element == elt
//
PVRelation * GetRelation(PVGraphElement*elt ,
RDir dir = eIn,
class Class * c = 0,
bool rIsKindOf =TRUE);
//
//This finds the incident relations with a certain dependency set
//
void GetRelsWithDep(ObjList & l, Events events, DepTypes type,RDir dir);
//
//This gets called by an incident relation when some event dependency changes
//
virtual void DepChange(Events event, DepTypes type){}
//
//This searches through the protos list trying to find some relation of
//type rc with tail and head of the same type of the tl and hd args.
//
PVRelation * GetDefaultRelation(PVGraphElement * tl,
PVGraphElement * hd,
class Class * rclass = 0 );
//
//These methods are used to add an element to this element.
//This adding is in effect adding a new relation between this element
//and the new element
//
void AddElement(PVGraphElement * elt, PVRelation * rel =0 );
void AddElements(Set *s);
};
#endif PVGraphElement_h